package com.galudisu.role.back

import akka.actor.{Actor, ActorLogging, ActorSystem, Props, RootActorPath}
import akka.cluster.ClusterEvent.{CurrentClusterState, MemberUp}
import akka.cluster.{Cluster, Member, MemberStatus}
import com.galudisu.comm.{JobSuccess, LogarithmCalcJob, Register}
import com.typesafe.config.ConfigFactory

/**
  * 角色为Backend
  *
  * @author galudisu
  */
class ClusterBackend extends Actor with ActorLogging {

  val cluster = Cluster(context.system)

  // subscribe to cluster changes, MemberUp
  // re-subscribe when restart
  override def preStart(): Unit = cluster.subscribe(self, classOf[MemberUp])
  override def postStop(): Unit = cluster.unsubscribe(self)

  override def receive: Receive = {

    case state: CurrentClusterState =>
      state.members.filter(_.status == MemberStatus.Up) foreach register
    case MemberUp(member) => register(member)
    case job: LogarithmCalcJob => sender() ! calc(job)

    case _ => None // do nothing here
  }

  def calc(job: LogarithmCalcJob): JobSuccess = {
    val radians = scala.math.toRadians(job.e)
    val result = scala.math.sin(radians)
    JobSuccess(s"sine of an angle ${job.e} is ${BigDecimal(result).setScale(2,BigDecimal.RoundingMode.HALF_UP)}")
  }

  def register(member: Member): Unit = {
    if (member.hasRole("frontend"))
      context.actorSelection(RootActorPath(member.address) / "user" / "frontend") ! Register
  }


}

object ClusterBackend extends App {

  val config = ConfigFactory.load("backend")
  val system = ActorSystem("ClusterSystem", config)

  val backend = system.actorOf(Props[ClusterBackend], name = "backend")

}


